<?php
class CryoBB_MakeTag
{
	protected $tags;
	protected $match;
	
	/**
	 * @var $tag
	 * @param object $match - the tag match from regexp search
	 */
	function __construct($tags, $match)
	{
		$this->tags = $tags;		
		$this->match = $match;		
	}
	
	/**
	 * Replaces a simple tag (e.g. [b]text[/b]) with it's HTML counterparts
	 *
	 * @param string $str The main string of text
	 * @param array $matches - The remaining tags
	 * @access private
	 */
	function makeTag($str, $matches)
	{
		// Get correct tag object
		$this->tag = $this->tags[$this->match->tag];
		
		// Handle ignoring
		if ($this->match->ignore)
		{
			return $this->match->match;
		}
		
		// Process/parse parameter and content
		if ($this->tag->parseParameter)
		{
			$this->match->reparseParameter($this->tags);
		}
		
		$this->match->processContent($this->tag);
		
		$this->match->processParameter($this->tag);
		
		// Get format from Tag object
		$replacement = $this->replacement();
		
		// Correct all following matches
		foreach ($matches as $otherMatch)
		{
			if ($otherMatch->inMatch($this->match))
			{
				$otherMatch->addOffset($this->innerOffset());
				
				if ($this->ignoreChildren())
				{
					$otherMatch->setIgnore(true);
				}
			} else
			{
				$otherMatch->addOffset($this->outerOffset());
			}
		}
		
		// Run replacement
		return $replacement;
	}
	
	function ignoreChildren()
	{
		return !$this->tag->parseContents;
	}
	
	/** Inner offset is the length difference between the bbcode opening tag, and the replacement opening tag.  For example, say we have a bbcode called [b] that has an opening tag of <strong>.  The offset would be 8 (the length of the replacement tag) minus 3 (the length of the bbcode tag), which would be 5.  That length must be know to add to the position of all tags held inside of that tag. */
	function innerOffset()
	{
		$build = $this->build();
		return $this->match->calculateOpenTagDifference($build[0]);
	}
	
	/** Outer offset is the total length difference.  So say we type [b]hello world[/b], the output would be <strong>hello world</strong>.  So the outer offset would be 28 minus 18, which is 10.  That length is added to all tags after that tag, and not inside. */
	function outerOffset()
	{
		return strlen($this->replacement()) - $this->match->length;
	}
	
	function replacement()
	{
		$build = $this->build();
		$replacement = $build[0] . $this->match->content . $build[1];
		return $replacement;
	}
	
	function build()
	{
		return $this->tag->build($this->match->parameter);
	}
}